#!/bin/bash
#
# Copyright 2020 Vincente <vincenteliang@foxmail.com>
# Copyright 2020-2021 Jason <jason23347@163.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# 1 to turn on debug mode, redirect log stream to stderr
DEBUG=0
# Send alert mail or not
DO_SEND_MAIL=1
# Randomly delay report submission for 0-${MAX_DELAY} minutes
RANDOM_DELAY=1
MAX_DELAY=20

MAX_RETRY=5
REPORT_SESSION=
# Recieving alert mail
EMAIL_ADDR=

LOG_DIR=/var/log
LOG_FILE=$LOG_DIR/ustb-report.log

REPORT_HOST=https://isport.ustb.edu.cn
REPORT_DATA="$(cat ~/report.data)"

# Using mutt by default,
# change to sendmail if you like
send_alert_mail() {
        [ $DO_SEND_MAIL -le 0 ] && return 0

        # Report at most once in an hour
        local -i timestamp=3600
        [ -f /tmp/ustb-last-error ] &&
                timestamp+=$(cat /tmp/ustb-last-error)
        [ $timestamp -gt $(date +%s) ] && {
                write_log "Ommitted to send alert mail within 1 hour."
                return 0
        }
        date +%s >/tmp/ustb-last-error

        mutt -s "USTB Report Warning" $EMAIL_ADDR <<END
An error occured with command $command at $(date +%T).
Here's the latest log:
$(tail -n 20 $LOG_FILE)

END
}

if [ $DEBUG -eq 0 ]; then
        RETRY_FREQUENCY=20 # seconds
else
        RETRY_FREQUENCY=2
fi

if [ $DEBUG -eq 0 ]; then
        # open log stream (append)
        exec 3>>$LOG_FILE
else
        exec 3>&2
fi

write_log() {
        printf "[%s] %s\n" "$(date +"%Y-%m-%d %H:%M:%S")" "$1" >&3
}

mycurl() {
        # Random delay
        if [ ${RANDOM_DELAY:-0} -eq 1 ]; then
                rnd=$((RANDOM % $MAX_DELAY))
                delay=$(($rnd * 60))
                write_log "Delay for $rnd minutes."
                sleep $delay
        fi
        message=$(curl -sL $REPORT_HOST/app.RSPWxClient/index.jsp \
                -H "X-Requested-With: XMLHttpRequest" \
                -H "Cookie: JSESSIONID=$REPORT_SESSION" \
                -d "$REPORT_DATA" |
                sed 's/.*\"message\":[[:space:]]\+\"//;s/\".*//')
        str='当天已上报You have submitted today.'
        write_log "$message"

        [ "x$message" == "x$str" ]
        return $?
}

[ $# -lt 1 ] && {
        echo "At least 1 argument required." >&2
        exit 1
}

command=$1
case $command in
submit)
        declare -i n=0
        while [ $n -lt $MAX_RETRY ]; do
                mycurl
                [ $? -eq 0 ] && break
                # Disable random delay for retries
                RANDOM_DELAY=0
                write_log "Retry will be after ${RETRY_FREQUENCY}(s)."
                sleep $RETRY_FREQUENCY
                n+=1
        done

        [ $n -ge $MAX_RETRY ] && {
                send_alert_mail
                exit 1
        }

        write_log "Submit succeed."
        ;;
ping)
        declare -i n=0
        while [ $n -lt $MAX_RETRY ]; do
                curl -sL $REPORT_HOST/app.RSPWxClient/index.jsp \
                        -H "Cookie: JSESSIONID=$REPORT_SESSION" \
                        -H "X-Requested-With: XMLHttpRequest"
                [ $? -eq 0 ] && break
                write_log "Ping failed."
                n+=1
        done

        [ $n -ge $MAX_RETRY ] && {
                send_alert_mail
                exit 1
        }

        write_log "Ping succeed."
        ;;
*)
        echo "Command $command not found." >&2
        ;;
esac
